
using System;
using System.Collections.Generic;

public class CardType
{
	public static Int32 none = 0;

	public static Int32 heitao = 1;

	public static Int32 hongtao = 2;

	public static Int32 meihua = 3;

	public static Int32 fangkuai = 4;

	// 底牌数量
	public static Int32 DipaiNum = 3;


}

public class PlayoutCardType
{
	// 无效
	public static Int32 Invalid = 0;
	// 单张
	public static Int32 Danzhang = 1;
	// 对子
	public static Int32 Duizi = 2;
	// 三不带
	public static Int32 Sanbudai = 3;
	// 三带一
	public static Int32 Sandaiyi = 4;
	// 连对
	public static Int32 Liandui = 5;
	// 顺子
	public static Int32 Shunzi = 6;
	// 炸弹
	public static Int32 Zhadan = 7;
	// 四带一
	public static Int32 Sidaiyi = 8;
	// 四带二
	public static Int32 Sidaier = 9;
	// 王炸
	public static Int32 Wangzha = 10;
	// 飞机
	public static Int32 Feiji = 11;
	// 最大
	public static Int32 Max = 12;

	public static int getShowCardsType(List<uint> showCards)
	{
		List<int> weightCards;
		if (!PlayoutCardType.getShowCardsWeight(showCards, out weightCards))
		{
			return PlayoutCardType.Invalid;
		}

		Dictionary<int, Func<List<int>, bool>> judgeTypeDict = new Dictionary<int, Func<List<int>, bool>> {
			{PlayoutCardType.Danzhang, isDanzhang },
			{PlayoutCardType.Duizi, isDuizi },
			{PlayoutCardType.Shunzi, isShunzi},
			{PlayoutCardType.Liandui, isLiandui },
			{PlayoutCardType.Sanbudai, isSanbudai },
			{PlayoutCardType.Sandaiyi, isSandaiyi },
			{PlayoutCardType.Feiji, isFeiji },
			{PlayoutCardType.Zhadan, isZhadan },
			{PlayoutCardType.Sidaiyi, isSidaiyi},
			{PlayoutCardType.Sidaier, isSidaier},
			{PlayoutCardType.Wangzha, isWangzha},
		};

		List<int> weightCardsTypes = new List<int>();

		foreach(var typeFuncPair in judgeTypeDict)
		{
			int cardType = typeFuncPair.Key;
			Func < List<int>, bool> func = typeFuncPair.Value;
			if (func(weightCards))
			{
				weightCardsTypes.Add(cardType);
			}
		}

		if(weightCardsTypes.Count < 1)
		{
			return PlayoutCardType.Invalid;
		}

		weightCardsTypes.Sort(
			(aCardType, bCardType) =>
			{
				if (aCardType == bCardType)
				{
					return 0;
				}

				int aTypeWeight;
				if (!CardDef.PlayoutCardTypeWeight.TryGetValue(aCardType, out aTypeWeight))
				{
					return -1;
				}

				int bTypeWeight;
				if (!CardDef.PlayoutCardTypeWeight.TryGetValue(bCardType, out bTypeWeight))
				{
					return -1;
				}

				return aTypeWeight > bTypeWeight ? -1 : 1;
			}
		);

		return weightCardsTypes[0];
	}

	private static bool getShowCardsWeight(List<uint> showCards, out List<int> weightCards)
	{
		weightCards = new List<int>();
		// 确保显示牌无重复的 
		//HashSet<uint> hsShowCards = new HashSet<uint>(showCards);
		//for (int i = 0; i < hsShowCards.Count; ++i)
		for (int i = 0; i < showCards.Count; ++i)
		{
			int weightCard = 0;
			if (! CardDef.CardsToWeight.TryGetValue(showCards[i], out weightCard))
			{
				return false;
			}

			weightCards.Add(weightCard);
		}

		weightCards.Sort(
			(left, right) =>
			{
				if (left == right)
				{
					return 0;
				}

				return left > right ? 1 : -1;
			}
		);

		return true;
	}

	private static bool isDanzhang(List<int> weightCards)
	{
		if (weightCards.Count != 1)
		{
			return false;
		}

		return true;
	}

	private static bool isDuizi(List<int> weightCards)
	{
		if (weightCards.Count != 2)
		{
			return false;
		}

		return weightCards[0] == weightCards[1];
	}

	private static bool isShunzi(List<int> weightCards)
	{
		if (weightCards.Count < 5)
		{
			return false;
		}

		for (int i = 1; i < weightCards.Count; ++i)
		{
			if (weightCards[i - 1] +1  != weightCards[i])
			{
				return false;
			}
		}

		return true;
	}

	private static bool isLiandui(List<int> weightCards)
	{
		if (weightCards.Count < 6 || weightCards.Count % 2 !=0)
		{
			return false;
		}

		for(int i = 2; i < weightCards.Count; i += 2)
		{
			if (weightCards[i - 2] != weightCards[i - 1 ] || weightCards[i - 2] +1 != weightCards[i])
			{
				return false;
			}
		}

		return true;
	}

	private static bool isSanbudai(List<int> weightCards)
	{
		if (weightCards.Count != 3)
		{
			return false;
		}

		return weightCards[0] == weightCards[1] && weightCards[1] == weightCards[2];
	}

	private static bool isSandaiyi(List<int> weightCards)
	{
		if (weightCards.Count != 4)
		{
			return false;
		}

		Dictionary<int, int> dictWeightCards = new Dictionary<int, int>();
		for(int i = 0; i < weightCards.Count; ++i)
		{
			int cnt;
			if (!dictWeightCards.TryGetValue(weightCards[i], out cnt))
			{
				dictWeightCards[weightCards[i]] = 0;
			}

			dictWeightCards[weightCards[i]] += 1;
		}

		foreach (var weightCardCntPair in dictWeightCards)
		{
			if(weightCardCntPair.Value == 3)
			{
				return true;
			}
		}

		return false;
	}

	private static bool isFeiji(List<int> weightCards)
	{
		if (weightCards.Count % 4 != 0 || weightCards.Count <= 4)
		{
			return false;
		}

		Dictionary<int, int> dictWeightCards = new Dictionary<int, int>();
		for (int i = 0; i < weightCards.Count; ++i)
		{
			int cnt;
			if (!dictWeightCards.TryGetValue(weightCards[i], out cnt))
			{
				dictWeightCards[weightCards[i]] = 0;
			}

			dictWeightCards[weightCards[i]] += 1;
		}

		List<int> sandai = new List<int>();

		foreach (var weightCardCntPair in dictWeightCards)
		{
			if (weightCardCntPair.Value >= 3) // 也有可能是炸弹凑成的飞机
			{
				sandai.Add(weightCardCntPair.Value);
			}
		}

		if(sandai.Count < 2)
		{
			return false;
		}

		for(int i = 1; i < sandai.Count; ++i)
		{
			if (sandai[i-1] + 1 != sandai[i])
			{
				return false;
			}
		}

		return true;
	}

	private static bool isZhadan(List<int> weightCards)
	{
		if (weightCards.Count != 4)
		{
			return false;
		}

		return weightCards[0] == weightCards[1] && weightCards[1] == weightCards[2] && weightCards[2] == weightCards[3];
	}

	private static bool isSidaiyi(List<int> weightCards)
	{
		if (weightCards.Count != 5)
		{
			return false;
		}

		Dictionary<int, int> dictWeightCards = new Dictionary<int, int>();
		for (int i = 0; i < weightCards.Count; ++i)
		{
			int cnt;
			if (!dictWeightCards.TryGetValue(weightCards[i], out cnt))
			{
				dictWeightCards[weightCards[i]] = 0;
			}

			dictWeightCards[weightCards[i]] += 1;
		}

		foreach (var weightCardCntPair in dictWeightCards)
		{
			if (weightCardCntPair.Value == 4)
			{
				return true;
			}
		}

		return false;
	}

	private static bool isSidaier(List<int> weightCards)
	{
		if (weightCards.Count != 6)
		{
			return false;
		}

		Dictionary<int, int> dictWeightCards = new Dictionary<int, int>();
		for (int i = 0; i < weightCards.Count; ++i)
		{
			int cnt;
			if (! dictWeightCards.TryGetValue(weightCards[i], out cnt))
			{
				dictWeightCards[weightCards[i]] = 0;
			}

			dictWeightCards[weightCards[i]] += 1;
		}

		foreach (var weightCardCntPair in dictWeightCards)
		{
			if (weightCardCntPair.Value == 4)
			{
				return true;
			}
		}

		return false;
	}

	private static bool isWangzha(List<int> weightCards)
	{
		if (weightCards.Count != 2)
		{
			return false;
		}

		if(weightCards[0] == CardDef.XiaoWangWeight && weightCards[1] == CardDef.DaWangWeight)
		{
			return true;
		}

		if(weightCards[1] == CardDef.XiaoWangWeight && weightCards[0] == CardDef.DaWangWeight)
		{
			return true;
		}

		return false;
	}
}


class CardDef
{
	List<uint> allCards = new List<uint> {
		// 黑桃
		103,//103,
		104,//104,
		105,//105,
		106,//106,
		107,//107,
		108,//108,
		109,//109,
		110,//110,
		111,//111,
		112,//112,
		113,//113,
		114,//114,
		115,//115,

		// 红桃
		203,//203,
		204,//204,
		205,//205,
		206,//206,
		207,//207,
		208,//208,
		209,//209,
		210,//210,
		211,//211,
		212,//212,
		213,//213,
		214,//214,
		215,//215,

		// 梅花
		303,//303,
		304,//304,
		305,//305,
		306,//306,
		307,//307,
		308,//308,
		309,//309,
		310,//310,
		311,//311,
		312,//312,
		313,//313,
		314,//314,
		315,//315,

		// 方块
		403,//403,
		404,//404,
		405,//405,
		406,//406,
		407,//407,
		408,//408,
		409,//409,
		410,//410,
		411,//411,
		412,//412,
		413,//413,
		414,//414,
		415,//415,

		// 大小王
		516,//516,
		517,//517,
	};

	public static Dictionary<int, List<uint>> WeightToCards = new Dictionary<int, List<uint>>{
		 { 3  , new List<uint>{103,203,303,403}},
		 { 4  , new List<uint>{104,204,304,404}},
		 { 5  , new List<uint>{105,205,305,405}},
		 { 6  , new List<uint>{106,206,306,406}},
		 { 7  , new List<uint>{107,207,307,407}},
		 { 8  , new List<uint>{108,208,308,408}},
		 { 9  , new List<uint>{109,209,309,409}},
		 {10 , new List<uint>{110,210,310,410}},
		 {11 , new List<uint>{111,211,311,411}},
		 {12 , new List<uint>{112,212,312,412}},
		 {13 , new List<uint>{113,213,313,413}},
		 {14 , new List<uint>{114,214,314,414}},
		 {15 , new List<uint>{102,202,302,402} },
		 {16 , new List<uint>{516}},
		 {17 , new List<uint>{517}},
	};

	public static Dictionary<uint, int> CardsToWeight = new Dictionary<uint, int>{
		{102, 15},
		{103,  3 },
		{104,  4 },
		{105,  5 },
		{106,  6 },
		{107,  7 },
		{108,  8 },
		{109,  9 },
		{110, 10},
		{111, 11},
		{112, 12},
		{113, 13},
		{114, 14},

		{202, 15},
		{203,  3 },
		{204,  4 },
		{205,  5 },
		{206,  6 },
		{207,  7 },
		{208,  8 },
		{209,  9 },
		{210, 10},
		{211, 11},
		{212, 12},
		{213, 13},
		{214, 14},

		{302, 15},
		{303,  3 },
		{304,  4 },
		{305,  5 },
		{306,  6 },
		{307,  7 },
		{308,  8 },
		{309,  9 }, 
		{310, 10},
		{311, 11},
		{312, 12},
		{313, 13},
		{314, 14},

		{402, 15},
		{403,  3 },
		{404,  4 },
		{405,  5 },
		{406,  6 },
		{407,  7 },
		{408,  8 },
		{409,  9 },
		{410, 10},
		{411, 11},
		{412, 12},
		{413, 13},
		{414, 14},

		{516, 16},
		{517, 17}
	};

	// 顺子最大最小权重
	public static Int32 ShunziMaxWeight = 14;
	public static Int32 ShunziMinWeight = 3;

	//对子最大最小权重;
	public static Int32 DuiziMaxWeight = 15;
	public static Int32 DuiziMinWeight = 3;

	//算大牌的权重;
	public static Int32 DapaiWeight = 15;

	//大小王权重;
	public static Int32 XiaoWangWeight = 16;
	public static Int32 DaWangWeight = 17;

	public static Int32 MinWeightCard = 3;


	// 出牌类型权重
	public static Dictionary<int, int> PlayoutCardTypeWeight = new Dictionary<int, int>{
		{PlayoutCardType.Danzhang , 1 },
		{PlayoutCardType.Duizi , 1},
		{PlayoutCardType.Sanbudai , 1},
		{PlayoutCardType.Sandaiyi , 1},
		{PlayoutCardType.Liandui , 1},
		{PlayoutCardType.Shunzi , 1},
		{PlayoutCardType.Zhadan , 2},
		{PlayoutCardType.Sidaiyi , 1},
		{PlayoutCardType.Sidaier , 1},
		{ PlayoutCardType.Wangzha , 3},
	};

}
